package com.gitee.wsl.time.sequence.sample

import com.gitee.wsl.time.sequence.InstantSequence
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
import kotlin.time.Instant

/**
 * A schedule which sends a specific sequence of [instants], rather than computing them. At each emission, the nearest
 * future Instant to the provided [clock] will be sent. When no such Instant exists, the schedule will complete.
 */
@OptIn(ExperimentalTime::class)
class FixedInstantInstant(
    private val instants: List<Instant>,
    private val clock: Clock,
) : InstantSequence {
    override fun generateSchedule(start: Instant): Sequence<Instant> {
        return sequence {
            while (true) {
                val now = clock.now()
                val nextInstant = getNextInstant(now) ?: return@sequence
                yield(nextInstant)
            }
        }
    }

    private fun getNextInstant(now: Instant): Instant? {
        return instants.firstOrNull { it > now }
    }

     companion object {
//         operator fun invoke(instants: List<Instant>, clock: Clock = Clock.System): FixedInstantInstant {
//            return FixedInstantInstant(
//                instants = instants.distinct().sorted(),
//                clock = clock,
//            )
//        }
//
//         operator fun invoke(vararg instants: Instant, clock: Clock = Clock.System): FixedInstantInstant {
//            return FixedInstantInstant(
//                instants = instants.distinct().sorted(),
//                clock = clock
//            )
//        }
    }
}

@OptIn(ExperimentalTime::class)
fun InstantSequence.Companion.fixedInstant(
    instants: List<Instant>,
    clock: Clock = Clock.System
): FixedInstantInstant {
    return FixedInstantInstant(
        instants = instants.distinct().sorted(),
        clock = clock
    )
}

@OptIn(ExperimentalTime::class)
fun InstantSequence.Companion.fixedInstant(
    vararg instants: Instant,
    clock: Clock = Clock.System
): FixedInstantInstant{
    return FixedInstantInstant(
        instants = instants.distinct().sorted(),
        clock = clock
    )
}